package ui;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DecimalFormat;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Button;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;

import components.PumpController;
import components.PumpController.BatteryStatus;

public class Gui {
	private static Text txtMain;
	
	final Display display;
	final Shell shlInsulinPump;
	ProgressBar progressBar_Battery;
	
	private PumpController pc;
	private int batteryLevel;
	private BatteryStatus batteryStatus;
	Boolean shutdown;
	
	public Gui(final PumpController pc) {
		display = Display.getDefault();
		shlInsulinPump = new Shell(SWT.TITLE);
		
		this.pc = pc;
		batteryLevel = pc.getBatteryLevel();
		batteryStatus = pc.getBatteryStatus();
		shutdown = false;

		shlInsulinPump.setSize(432, 314);
		shlInsulinPump.setText("Insulin Pump");
		
		final Composite composite_Main = new Composite(shlInsulinPump, SWT.NONE);
		composite_Main.setBounds(62, 0, 361, 282);
		
		final Label lblState = new Label(composite_Main, SWT.BORDER | SWT.CENTER);
		lblState.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		lblState.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_DARK_SHADOW));
		lblState.setFont(SWTResourceManager.getFont("Tahoma", 13, SWT.NORMAL));
		lblState.setBounds(136, 9, 85, 26);
		lblState.setText("Idle");
		
		final Button btnStop = new Button(composite_Main, SWT.NONE);
		final Button btnStartPause = new Button(composite_Main, SWT.NONE);
		final Button btnChangeProfile = new Button(composite_Main, SWT.CENTER);
		btnStop.setEnabled(false);
		btnStop.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				pc.setStopped();
				btnStartPause.setText("Start");
				lblState.setText("Stopped");
				btnStop.setEnabled(false);
				btnStartPause.setEnabled(false);
				
				// Clear the loaded profile
				pc.getInsulinManager().setCurrentProfile(null);
				txtMain.setText("*No profile loaded! Please load a profile by clicking 'Load Profile' below.");
				btnChangeProfile.setText("Load Profile");
			}
		});
		btnStop.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		btnStop.setBounds(187, 190, 82, 92);
		btnStop.setText("Stop");
		
		btnStartPause.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
			}
		});
		btnStartPause.setEnabled(false);
		btnStartPause.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {						// StartPause button clicked. Put code here. *SR
				btnStop.setEnabled(true);
				
				// Toggle between Start and Pause
				if (btnStartPause.getText() == "Start") {
					pc.setRunning();
					btnStartPause.setText("Pause"); 
					lblState.setText("Running");
				} else {
					pc.setPaused();
					btnStartPause.setText("Start");
					lblState.setText("Paused");
				}
				
			}
		});
		btnStartPause.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		btnStartPause.setBounds(275, 190, 82, 92);
		btnStartPause.setText("Start");
		
		Button btnPower = new Button(composite_Main, SWT.NONE);
		btnPower.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				// set shutdown flag
				shutdown = true;
			}
		});
		
		btnPower.setImage(SWTResourceManager.getImage(Gui.class, "/ui/Standby_Symbol.png"));
		btnPower.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		btnPower.setForeground(SWTResourceManager.getColor(0, 0, 0));
		btnPower.setBounds(275, 5, 82, 31);
		btnPower.setText("Power");
		
		final Label lblDateTime = new Label(composite_Main, SWT.NONE);
		lblDateTime.setBounds(10, 10, 168, 15);
		lblDateTime.setText("{*CURRENT DATETIME HERE*}");
		final DateFormat timeFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); // For the displayed clock
		
		txtMain = new Text(composite_Main, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP);
		txtMain.setFont(SWTResourceManager.getFont("Times New Roman", 14, SWT.NORMAL));
		txtMain.setText("*No profile loaded! Please load a profile by clicking 'Load Profile' below.");
		txtMain.setBackground(SWTResourceManager.getColor(255, 255, 255));
		txtMain.setBounds(10, 55, 345, 82);
		
		Label lblProfile = new Label(composite_Main, SWT.NONE);
		lblProfile.setBounds(10, 34, 55, 15);
		lblProfile.setText("Profile:");
		
		
		btnChangeProfile.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				
				// Pop profile loader dialog. *SR
				ProfileLoader pl = new ProfileLoader(shlInsulinPump, SWT.NONE);
				pl.open(pc);
				
				// Check if profile loaded
				if (pc.getInsulinManager().isProfileLoaded() == true)
				{
					btnChangeProfile.setText("Change Profile");
					btnStartPause.setEnabled(true);
					
					String curProfile = pc.getInsulinManager().getCurrentProfileName();
					int curRate = pc.getInsulinManager().getCurrentBasalRate();
					txtMain.setText("Profile: " + curProfile + "\r\nCurrent Rate: " + ((float)curRate)/10 + " Units/Hour");
				}
			}
		});
		btnChangeProfile.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		btnChangeProfile.setBounds(187, 143, 168, 31);
		btnChangeProfile.setText("Load Profile");
		
		Button btnProfileInformation = new Button(composite_Main, SWT.CENTER);
		btnProfileInformation.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {

				// Pop profile details dialog. *SR
				ProfileInformation pl = new ProfileInformation(shlInsulinPump, SWT.NONE);
				pl.open(pc.getInsulinManager().getCurrentProfileName());
			}
		});
		btnProfileInformation.setText("Profile Information");
		btnProfileInformation.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		btnProfileInformation.setBounds(10, 143, 168, 31);
		
		Label label_Divide = new Label(composite_Main, SWT.SEPARATOR | SWT.HORIZONTAL);
		label_Divide.setBounds(10, 180, 345, 4);
		
		Group grpBolusControl = new Group(composite_Main, SWT.NONE);
		grpBolusControl.setText("Bolus Control");
		grpBolusControl.setBounds(10, 181, 172, 101);
		
		final Label lblDosage = new Label(grpBolusControl, SWT.BORDER | SWT.RIGHT);
		lblDosage.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				Keypad kp = new Keypad(shlInsulinPump, SWT.NONE);
				kp.open();
			}
		});
		lblDosage.setFont(SWTResourceManager.getFont("Segoe UI", 11, SWT.NORMAL));
		lblDosage.setBounds(89, 22, 73, 25);
		lblDosage.setText("0");
		
		Button btnBolus = new Button(grpBolusControl, SWT.NONE);
		btnBolus.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				
				// Dosage confimation popup *SR
				DosageConfim dc = new DosageConfim(shlInsulinPump, SWT.NONE);
				dc.open(lblDosage.getText(), pc);
			}
		});
		btnBolus.setBounds(10, 22, 71, 69);
		btnBolus.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		btnBolus.setText("Administer");
		
		Button btnBolusMinus = new Button(grpBolusControl, SWT.NONE);
		btnBolusMinus.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try
				{
					float dosage = Float.parseFloat(lblDosage.getText());
					if (dosage > 0) { dosage-=0.1; }
					lblDosage.setText( new DecimalFormat("#0.0").format(dosage) );
				}
				catch (Exception ex)
				{
					System.out.println("ERROR: Failed to decrement dosage. Exception: " + ex.toString());
				}
			}
		});
		btnBolusMinus.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.BOLD));
		btnBolusMinus.setBounds(87, 53, 37, 38);
		btnBolusMinus.setText("-");
		
		Button btnBolusPlus = new Button(grpBolusControl, SWT.NONE);
		btnBolusPlus.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try
				{
					float dosage = Float.parseFloat(lblDosage.getText());
					if (dosage < 10) { dosage = (float)(dosage + 0.1); }
					lblDosage.setText( new DecimalFormat("#0.0").format(dosage) );
				}
				catch (Exception ex)
				{
					System.out.println("ERROR: Failed to increment dosage. Exception: " + ex.toString());
				}
			}
		});
		btnBolusPlus.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.BOLD));
		btnBolusPlus.setText("+");
		btnBolusPlus.setBounds(125, 53, 37, 38);
		
		Composite composite_Battery = new Composite(shlInsulinPump, SWT.NONE);
		composite_Battery.setBounds(5, 0, 56, 282);
		
		progressBar_Battery = new ProgressBar(composite_Battery, SWT.VERTICAL);
		progressBar_Battery.setSelection(100);
		progressBar_Battery.setBounds(0, 5, 56, 277);
		
		
		
		
		
		
		// Update GUI values from PumpController every second
		final int time = 1000;
	    Runnable timer = new Runnable() {
	    	public void run() {
	    		Gui.this.update(); 
	    		display.timerExec(time, this);
	    	}
	    };
	    display.timerExec(time, timer);
		
		
	    
	    
	    
		

		shlInsulinPump.open();
		shlInsulinPump.layout();
		
		Boolean insulinWarning = true;
		while (!shlInsulinPump.isDisposed() && !shutdown) {
			if (!display.readAndDispatch()) {
				display.sleep();
				
				// Check Bolus
				if (insulinWarning && (20 < (pc.pumpDosageTotal + pc.getInsulinManager().bolusDosageTotal)) )
				{
					insulinWarning = false;
					BolusLimitWarning blw = new BolusLimitWarning(shlInsulinPump, SWT.NONE);
					blw.open();
				}
				
				// Date and time display *SR
				lblDateTime.setText(timeFormat.format(new Date()));	// Device clock
			}
		}
		
		// shutting down		
		pc.setOff();
		display.timerExec(-1, timer);
		
		// display powering down screen
		composite_Main.setEnabled(false);
		composite_Battery.setEnabled(false);
		PowerDown pd = new PowerDown(shlInsulinPump, SWT.NONE);
		pd.open();
		
		// Close the application *SR
		display.dispose();
		System.exit(time);
	}

	protected void update() {
		updateBattery();
	}
	
	protected void updateBattery() {
		batteryLevel = pc.getBatteryLevel();
		progressBar_Battery.setSelection(batteryLevel);
		
		BatteryStatus newBatteryStatus = pc.getBatteryStatus();
		
		// update battery bar color if need be
		if (newBatteryStatus != batteryStatus) {
			batteryStatus = newBatteryStatus;
			
			switch(batteryStatus) {
				case Normal:
					// Turn bar green to indicate normal battery
					progressBar_Battery.setState(SWT.NORMAL);
					break;
				case Warning:
					// Turn bar yellow to indicate warning battery
					progressBar_Battery.setState(SWT.PAUSED);
					break;
				case Low:
					// Turn bar red to indicate low battery
					progressBar_Battery.setState(SWT.ERROR);
					
					LowBatWarning lbw = new LowBatWarning(shlInsulinPump, SWT.NONE);
					lbw.open();
					break;
				case Depleted:
					// set the shutdown flag because battery is dead
					shutdown = true;
					break;
			}
		}
	}

	public PumpController getPc() {
		return pc;
	}
}
